#ifndef XCALL_H
#define XCALL_H
#include <xscript/xdefs.h>
#include <xscript/xerror.h>
#include <xscript/xtoken.h>
#include <xscript/xvariabletable.h>

class XCall {
  public:
    typedef std::shared_ptr<XCall> XCallPtr;
    enum XCallType {
        XCallType_Let = 0,
        XCallType_Set,
        XCallType_Boolean,
        XCallType_Print,
        XCallType_Function,
        XCallType_Block,
        XCallType_IF,
        XCallType_Max
    };

    static std::shared_ptr<XCall> makeCall(const std::wstring& name, std::shared_ptr<XToken> inputToken);
    XCall() = delete;
    XCall(std::shared_ptr<XToken> token);
    virtual ~XCall() = default;
  public:
    std::wstring getName()const;
    virtual XCallType getType()const = 0;
    virtual bool invoke(std::shared_ptr<XVariableTable> table) = 0;
    virtual void addArgument(std::shared_ptr<XItem> argument);

    size_t countOfArguments()const;

    virtual void clear();

    void setResult(std::shared_ptr<XItem> value);

    std::shared_ptr<XToken> getToken()const;

    virtual std::shared_ptr<XItem> getResult();
  protected:
    std::shared_ptr<XItem> getValueFromToken(std::shared_ptr<XVariableTable> table, std::shared_ptr<XToken> token);
    bool swtichVariableTable(std::shared_ptr<XVariableTable> table, const std::wstring& module, uint32_t block);
  protected:
    std::wstring name;
    std::shared_ptr<XToken> token;
    std::vector<std::shared_ptr<XItem>> arguments;
    std::shared_ptr<XItem> result;
};

#endif // XCALL_H
